<template>
  <el-dialog
    title="站点位置"
    v-model="mapShow"
    @close="closeMap"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    width="800px"
  >
    <el-input
      v-model="keyword"
      @keyup.enter="search"
      class="search-input"
      placeholder="请输入关键词"
    >
      <template #append>
        <el-icon @click="search()"><Search /></el-icon>
      </template>
    </el-input>
    <div class="map-con" id="map"></div>
    <div class="address-list" v-if="searchResults.length > 0">
      <ul>
        <li v-for="(item, index) in searchResults" :key="index" @click="selectAddress(item)">
          {{ item.title }}
        </li>
      </ul>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="closeMap">取消</el-button>
        <el-button type="primary" @click="confirmLocation">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { ref, onBeforeUnmount } from "vue";
import { Search } from "@element-plus/icons-vue";

const keyword = ref("");
const mapShow = ref(false);
let map: any = null;
let marker: any = null;
const searchResults = ref<any[]>([]);
const selectedLocation = ref<{ lng: number; lat: number; address?: string } | null>(null);
const tencentMapKey = "AUGBZ-AD3EZ-MT6XQ-TMFGS-XB6M2-3OFJK"; // 请替换为实际的腾讯地图key
let mapInitialized = false; // 标记地图是否已初始化

// 初始化地图
const initMap = () => {
  if (!(window as any).TMap) {
    ElMessage.error("地图加载失败，请检查网络连接");
    return;
  }

  // 确保地图容器已挂载到DOM
  const mapContainer = document.getElementById("map");
  if (!mapContainer) {
    ElMessage.error("地图容器未找到");
    return;
  }

  // 只初始化一次地图
  if (!mapInitialized) {
    map = new (window as any).TMap.Map("map", {
      center: new (window as any).TMap.LatLng(39.9042, 116.4074),
      zoom: 15,
      pitch: 0,
    });

    // 使用 MultiMarker 创建可拖动标记
    marker = new (window as any).TMap.MultiMarker({
      id: "marker-layer",
      map: map,
      styles: {
        marker: new (window as any).TMap.MarkerStyle({
          width: 26,
          height: 38,
          anchor: { x: 13, y: 38 },
        }),
      },
      geometries: [
        {
          id: "marker",
          styleId: "marker",
          position: new (window as any).TMap.LatLng(39.9042, 116.4074),
          properties: {
            draggable: true, // 设置标记可拖动
          },
        },
      ],
    });

    // 监听标记拖动结束事件
    marker.on("dragend", (e: any) => {
      const position = e.geometry.position;
      selectedLocation.value = {
        lng: position.getLng(),
        lat: position.getLat(),
      };

      // 获取地址信息
      getAddressFromLatLng(position.getLat(), position.getLng());
    });

    // 监听地图点击事件
    map.on("click", (event: any) => {
      const position = event.latLng;
      // 更新标记位置
      marker.updateGeometries([
        {
          id: "marker",
          styleId: "marker",
          position: position,
          properties: {
            draggable: true, // 确保新位置的标记也是可拖动的
          },
        },
      ]);

      selectedLocation.value = {
        lng: position.getLng(),
        lat: position.getLat(),
      };

      // 获取地址信息
      getAddressFromLatLng(position.getLat(), position.getLng());
    });

    mapInitialized = true;
  }
};

// 通过经纬度获取地址信息
const getAddressFromLatLng = (lat: number, lng: number) => {
  const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${tencentMapKey}&output=jsonp`;

  jsonp(url)
    .then((data: any) => {
      if (data.status === 0 && data.result) {
        const address = data.result.address || "";
        if (selectedLocation.value) {
          selectedLocation.value.address = address;
        }
      }
    })
    .catch((err) => {
      console.error("获取地址信息失败:", err);
    });
};

// 设置地图和标记位置
const setMapPosition = (lng: number, lat: number) => {
  if (!map || !marker) return;

  const position = new (window as any).TMap.LatLng(lat, lng);
  map.setCenter(position);

  // 更新标记位置
  marker.updateGeometries([
    {
      id: "marker",
      styleId: "marker",
      position: position,
      properties: {
        draggable: true,
      },
    },
  ]);

  selectedLocation.value = {
    lng,
    lat,
  };

  // 获取地址信息
  getAddressFromLatLng(lat, lng);
};

// 加载腾讯地图API
const loadMapScript = (callback: () => void) => {
  if ((window as any).TMap) {
    callback();
    return;
  }

  // 添加libraries=service参数以启用服务类
  const script = document.createElement("script");
  script.type = "text/javascript";
  script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${tencentMapKey}&libraries=service`;
  script.onload = () => {
    // 等待一段时间确保服务类加载完成
    setTimeout(() => {
      callback();
    }, 500);
  };
  script.onerror = () => {
    ElMessage.error("地图加载失败，请检查网络连接");
  };
  document.head.appendChild(script);
};

const closeMap = () => {
  mapShow.value = false;
  keyword.value = "";
  searchResults.value = [];
};

const open = (lng?: string, lat?: string) => {
  mapShow.value = true;

  // 使用 nextTick 确保 DOM 已更新
  setTimeout(() => {
    loadMapScript(() => {
      initMap();

      // 如果提供了坐标，则设置地图位置
      if (lng && lat) {
        setMapPosition(parseFloat(lng), parseFloat(lat));
      } else {
        // 默认位置
        setMapPosition(116.4074, 39.9042);
      }

      // 清空搜索关键词
      keyword.value = "";
      searchResults.value = [];
    });
  }, 0);
};

const emits = defineEmits(["pick"]);

// JSONP 工具函数
const jsonp = (url: string, callbackParam: string = "callback"): Promise<any> => {
  return new Promise((resolve, reject) => {
    const callbackName = "jsonp_callback_" + Math.round(100000 * Math.random());
    const script = document.createElement("script");

    (window as any)[callbackName] = function (data: any) {
      delete (window as any)[callbackName];
      document.body.removeChild(script);
      resolve(data);
    };

    script.src = url + (url.indexOf("?") >= 0 ? "&" : "?") + callbackParam + "=" + callbackName;
    script.onerror = (err) => {
      delete (window as any)[callbackName];
      document.body.removeChild(script);
      reject(err);
    };

    document.body.appendChild(script);
  });
};

// 搜索地点 - 使用腾讯地图WebService API的JSONP方式
const search = () => {
  if (!keyword.value.trim()) {
    searchResults.value = [];
    return;
  }

  // 使用腾讯地图的WebService API进行地点搜索 (JSONP方式解决跨域)
  const url = `https://apis.map.qq.com/ws/place/v1/suggestion?keyword=${encodeURIComponent(
    keyword.value
  )}&key=${tencentMapKey}&region=全国&output=jsonp`;

  jsonp(url)
    .then((data: any) => {
      if (data.status === 0) {
        searchResults.value = data.data.slice(0, 10); // 只取前10个结果
      } else {
        ElMessage.error("搜索失败：" + data.message);
      }
    })
    .catch((err) => {
      console.error("搜索出错:", err);
      ElMessage.error("搜索失败，请重试");
    });
};

// 选择搜索结果中的地址
const selectAddress = (item: any) => {
  const lat = item.location.lat;
  const lng = item.location.lng;

  // 更新地图中心点和标记位置
  setMapPosition(lng, lat);

  searchResults.value = [];
  keyword.value = item.title;
};

// 确认选择的位置
const confirmLocation = () => {
  if (selectedLocation.value) {
    emits("pick", {
      lng: selectedLocation.value.lng,
      lat: selectedLocation.value.lat,
      address: selectedLocation.value.address || keyword.value || "",
    });
    closeMap();
  } else {
    ElMessage.warning("请先选择位置");
  }
};

defineExpose({ open });

// 组件卸载前清理
onBeforeUnmount(() => {
  if (marker) {
    marker.setMap(null);
  }
  if (map) {
    map.destroy();
  }
  mapInitialized = false;
});
</script>

<style lang="scss" scoped>
.search-input {
  margin-bottom: 15px;
}

.map-con {
  width: 100%;
  height: 400px;
}

.address-list {
  margin-top: 15px;
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid #ebeef5;

  ul {
    padding: 0;
    margin: 0;

    li {
      list-style: none;
      padding: 8px 12px;
      border-bottom: 1px solid #ebeef5;
      cursor: pointer;

      &:hover {
        background-color: #f5f7fa;
      }

      &:last-child {
        border-bottom: none;
      }
    }
  }
}

.dialog-footer {
  text-align: right;
}
</style>
